package cloudContact.servlet;

import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.net.URL;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.mybeans.factory.RollbackException;

import com.google.gdata.client.Query;
import com.google.gdata.client.authn.oauth.GoogleOAuthHelper;
import com.google.gdata.client.authn.oauth.GoogleOAuthParameters;
import com.google.gdata.client.authn.oauth.OAuthException;
import com.google.gdata.client.authn.oauth.OAuthHmacSha1Signer;
import com.google.gdata.client.contacts.ContactsService;
import com.google.gdata.data.Link;
import com.google.gdata.data.contacts.ContactEntry;
import com.google.gdata.data.contacts.ContactFeed;
import com.google.gdata.data.contacts.ContactGroupEntry;
import com.google.gdata.data.contacts.GroupMembershipInfo;
import com.google.gdata.data.extensions.Email;
import com.google.gdata.data.extensions.ExtendedProperty;
import com.google.gdata.data.extensions.Im;
import com.google.gdata.data.extensions.Name;
import com.google.gdata.util.ServiceException;
import com.google.gson.Gson;

import cloudContact.Common;
import cloudContact.GoogleConstant;
import cloudContact.MyDAOException;
import cloudContact.SecurityManager;
import cloudContact.DAO.*;

/**
 * Servlet implementation class Contact
 */
@WebServlet("/Contact")
public class Contact extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public Contact() {
		super();
		// TODO Auto-generated constructor stub
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		System.out.println("Start Contact...");

		response.setContentType("text/plain");
		PrintWriter out = response.getWriter();
		try {
			if (!SecurityManager.CheckAuthorization(request)) {
				out.println("Error: User is not authorized.");
				return;
			}

			HttpSession session = request.getSession();

			GoogleOAuthParameters oauthParameters = new GoogleOAuthParameters();

			oauthParameters.setOAuthConsumerKey(GoogleConstant.CONSUMER_KEY);
			oauthParameters
					.setOAuthConsumerSecret(GoogleConstant.CONSUMER_SECRET);
			oauthParameters.setOAuthToken((String) session
					.getAttribute("auth_token"));
			oauthParameters.setOAuthTokenSecret((String) session
					.getAttribute("auth_token_secret"));

			// GoogleContactDAO gContactDAO = new
			// GoogleContactDAO(oauthParameters);
			//
			// Hashtable<ContactGroupEntry, ArrayList<GoogleContact>> ctWthGrp =
			// gContactDAO.getAllContactsWithGroup();
			//
			// // Outer Hashtable is between group name and list of member,
			// inner hashtable is between contact id and full name.
			// Hashtable<String, Hashtable<String, String>> grpWthFullName = new
			// Hashtable<String, Hashtable<String, String>>();
			//
			// for (Map.Entry<ContactGroupEntry, ArrayList<GoogleContact>> group
			// : ctWthGrp.entrySet()) {
			//
			// Hashtable<String, String> shortContact = new Hashtable<String,
			// String>();
			//
			// for (GoogleContact contact : group.getValue()) {
			// if (contact != null) {
			// shortContact.put(contact.getContactId(), contact.getFullName());
			// } else {
			// System.out.println("Why contact is null?");
			// }
			//
			// }
			//
			// grpWthFullName.put(group.getKey().getTitle().getPlainText(),
			// shortContact);
			// }
			//
			// Gson gSon = new Gson();
			// out.print(gSon.toJson(grpWthFullName));

			ContactsService myService = new ContactsService(
					"CloudContact-CloudContact-1");

			try {
				myService.setOAuthCredentials(oauthParameters,
						new OAuthHmacSha1Signer());
			} catch (OAuthException e) {
				e.printStackTrace();
			}

			try {
				printAllContacts(myService);
			} catch (ServiceException e) {
				e.printStackTrace();
			}

			// } catch (OAuthException e) {
			// out.print(Common.CriticalErrorRaised(e));
			// } catch (ServiceException e) {
			// out.print(Common.CriticalErrorRaised(e));
		} catch (RollbackException e) {
			out.print(Common.CriticalErrorRaised(e));
		} catch (MyDAOException e) {
			out.print(Common.CriticalErrorRaised(e));
		} finally {
			out.flush();
			out.close();
			System.out.println("Finish Contact.");
		}

	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

	}

	private static PrintStream output = System.out;

	private static void printLnMsg(String msg) {
		output.println(msg);
	}

	private static void printMsg(String msg) {
		output.print(msg);
	}

	// /
	// /
	// http://code.google.com/apis/contacts/docs/3.0/developers_guide_java.html#Retrieving
	// /
	public static void printAllContacts(ContactsService myService)
			throws ServiceException, IOException {
		// Request the feed
		URL feedUrl = new URL(
				"https://www.google.com/m8/feeds/contacts/default/full");
		Query myQuery = new Query(feedUrl);
		myQuery.setMaxResults(10000);
		// myQuery.setStringCustomParameter("xoauth_requestor_id",
		// "sompops@gmail.com");
		ContactFeed resultFeed = myService.query(myQuery, ContactFeed.class);
		// ContactFeed resultFeed = myService.getFeed(feedUrl,
		// ContactFeed.class);
		// Print the results
		printLnMsg(resultFeed.getTitle().getPlainText());
		printLnMsg("Number of contacts = " + resultFeed.getEntries().size());
		for (int i = 0; i < resultFeed.getEntries().size(); i++) {
			ContactEntry entry = resultFeed.getEntries().get(i);
			if (entry.hasName()) {
				Name name = entry.getName();
				if (name.hasFullName()) {
					String fullNameToDisplay = name.getFullName().getValue();
					if (name.getFullName().hasYomi()) {
						fullNameToDisplay += " ("
								+ name.getFullName().getYomi() + ")";
					}
					printLnMsg("\t\t" + fullNameToDisplay);
				} else {
					printLnMsg("\t\t (no full name found)");
				}
				if (name.hasNamePrefix()) {
					printLnMsg("\t\t" + name.getNamePrefix().getValue());
				} else {
					printLnMsg("\t\t (no name prefix found)");
				}
				if (name.hasGivenName()) {
					String givenNameToDisplay = name.getGivenName().getValue();
					if (name.getGivenName().hasYomi()) {
						givenNameToDisplay += " ("
								+ name.getGivenName().getYomi() + ")";
					}
					printLnMsg("\t\t" + givenNameToDisplay);
				} else {
					printLnMsg("\t\t (no given name found)");
				}
				if (name.hasAdditionalName()) {
					String additionalNameToDisplay = name.getAdditionalName()
							.getValue();
					if (name.getAdditionalName().hasYomi()) {
						additionalNameToDisplay += " ("
								+ name.getAdditionalName().getYomi() + ")";
					}
					printLnMsg("\t\t" + additionalNameToDisplay);
				} else {
					printLnMsg("\t\t (no additional name found)");
				}
				if (name.hasFamilyName()) {
					String familyNameToDisplay = name.getFamilyName()
							.getValue();
					if (name.getFamilyName().hasYomi()) {
						familyNameToDisplay += " ("
								+ name.getFamilyName().getYomi() + ")";
					}
					printLnMsg("\t\t" + familyNameToDisplay);
				} else {
					printLnMsg("\t\t (no family name found)");
				}
				if (name.hasNameSuffix()) {
					printLnMsg("\t\t" + name.getNameSuffix().getValue());
				} else {
					printLnMsg("\t\t (no name suffix found)");
				}
			} else {
				printLnMsg("\t (no name found)");
			}

			printLnMsg("Email addresses:");
			for (Email email : entry.getEmailAddresses()) {
				printMsg(" " + email.getAddress());
				if (email.getRel() != null) {
					printMsg(" rel:" + email.getRel());
				}
				if (email.getLabel() != null) {
					printMsg(" label:" + email.getLabel());
				}
				if (email.getPrimary()) {
					printMsg(" (primary) ");
				}
				printMsg("\n");
			}

			printLnMsg("IM addresses:");
			for (Im im : entry.getImAddresses()) {
				printMsg(" " + im.getAddress());
				if (im.getLabel() != null) {
					printMsg(" label:" + im.getLabel());
				}
				if (im.getRel() != null) {
					printMsg(" rel:" + im.getRel());
				}
				if (im.getProtocol() != null) {
					printMsg(" protocol:" + im.getProtocol());
				}
				if (im.getPrimary()) {
					printMsg(" (primary) ");
				}
				printMsg("\n");
			}

			printLnMsg("Groups:");
			for (GroupMembershipInfo group : entry.getGroupMembershipInfos()) {
				String groupHref = group.getHref();
				printLnMsg("  Id: " + groupHref);
			}

			printLnMsg("Extended Properties:");
			for (ExtendedProperty property : entry.getExtendedProperties()) {
				if (property.getValue() != null) {
					printLnMsg("  " + property.getName() + "(value) = "
							+ property.getValue());
				} else if (property.getXmlBlob() != null) {
					printLnMsg("  " + property.getName() + "(xmlBlob)= "
							+ property.getXmlBlob().getBlob());
				}
			}

			Link photoLink = entry.getContactPhotoLink();
			String photoLinkHref = photoLink.getHref();
			printLnMsg("Photo Link: " + photoLinkHref);

			if (photoLink.getEtag() != null) {
				printLnMsg("Contact Photo's ETag: " + photoLink.getEtag());
			}

			printLnMsg("Contact's ETag: " + entry.getEtag());
		}
	}

}
